/**
 * @author dss
 */
_dss_editor._canvas._system_layer = {};
_dss_editor._canvas._link_layer = {};

_dss_editor._canvas._system_layer.create = function(canvas) {
	var layer = {};
	var that = this;
	layer.canvas = canvas;
	layer.draw = function() {
		if (this.canvas.sys.hasOwnProperty('getChildren')) {
			var systems = this.canvas.sys.getChildren();
			that.drawSystems(systems, this.canvas);
		}
	};

	layer.layout = function() {

	};
	return layer;
};
/* 绘制cotent box */
_dss_editor._canvas._system_layer.drawContentBox = function(system, ctx, canvasType) {
	// 绘制矩形
	var bounds = _dss_editor._toolkit.translateToAbsolute(system);
	//var canvasEntity = this.canvas.entity;
	var x = bounds.x + 0.5;
	var y = bounds.y + 0.5;
	var w = bounds.w;
	var h = bounds.h;

	var textX = bounds.x + 21;
	var textY = bounds.y + 16;
	//var ctx = _dss_editor._toolkit.getContext(canvasEntity);

	if (system.isShowLabel()) {
		y += labelHeight;
		h -= labelHeight;
		textY += labelHeight;
	}

	if (system.getDeriveFlag() == SENDER) {
		w -= deriveOffset;
	}

	// 绘制shadow
	ctx.save();
	if (system.hasShadow() == SHOW) {
		ctx.shadowBlur = 1;
		ctx.shadowColor = 'gray';
		ctx.shadowOffsetX = 4;
		ctx.shadowOffsetY = 4;
	}
	// 绘制主体 由于可能有影子所以必须画实心的矩形。边框需用空心矩形
	ctx.fillStyle = 'white';
	// ctx.strokeStyle = getSystemColor(system);
	ctx.fillRect(x + 1, y + 1, w - 2, h - 2);
	ctx.restore();
	// 实心矩形略小，不影响边框的线条
	ctx.strokeRect(x, y, w, h);
	// 如果是有接收发送消息，则画其三角形
	this.drawDeriveFlag(system, ctx, x, y, w, h);

	// 绘制content
	ctx.fillStyle = 'black';
	if (system.getSystemComplexity() == 1) {
		ctx.fillText(system.getValue(), textX, textY);
		if (system.getType() == _dss_editor._model.system._type.PROTOCOL) {
			this.drawSimpleProDir(ctx, bounds, system);
		}
	} else if (system.getSystemComplexity() > 1) {
		ctx.save();
		this.clip(ctx, x, y, w, h);
		//ctx.scale(0.5,0.5);
		var children = system.getChildren();
		for (var i = 0; i < children.length; i++) {
			var child = children[i];
			this.drawDiagram(child,ctx,canvasType);
		}
		ctx.restore();
	}
	// 绘制实例化图标
	if (system.isInstantiate()) {
		var icon = new Image();
		icon.src = ICON_INSTANTIATE;
		ctx.drawImage(icon, x + w - 16, y + 2);
	}

};

_dss_editor._canvas._system_layer.drawDiagram = function(diagram, ctx, canvasType) {
	if (diagram.style == SYSTEM) {
		this.drawSystem(diagram, ctx, canvasType);
	} else if (diagram.style == ARRAY) {
		this.drawArray(diagram, ctx, canvasType);
	} else if (diagram.type == BEGINPOINT) {
		this.drawBeginPoint(diagram, ctx);
	} else if (diagram.type == ENDPOINT) {
		this.drawEndPoint(diagram, ctx);
	} else if (diagram.type == EXITPOINT) {
		this.drawExitPoint(diagram, ctx);
	} else if (diagram.type == PRECOND) {
		this.drawPreCondition(diagram, ctx);
	} else if (diagram.type == POSTCOND) {
		this.drawPostCondition(diagram, ctx);
	}
};

_dss_editor._canvas._system_layer.clip = function(ctx, x, y, w, h) {
	ctx.beginPath();
	y += 2;
	h -= 4;
	x += 2;
	w -= 4;
	ctx.moveTo(x, y);
	ctx.lineTo(x + w, y);
	ctx.lineTo(x + w, y + h);
	ctx.lineTo(x, y + h);
	ctx.lineTo(x, y);
	ctx.clip();
};

_dss_editor._canvas._system_layer.drawArray = function(array, ctx, canvasType) {
	for (var i in array.subInstance) {
		var instance = array.subInstance[i];
		this.drawSystem(instance, ctx, canvasType);
	}
};

_dss_editor._canvas._system_layer.drawDeriveFlag = function(system, ctx, x, y, w, h) {
	var hasMsg = false;
	if (system.hasOwnProperty('content')) {
		if (system.content.hasOwnProperty('simple') && system.content.simple.hasOwnProperty('expr') && system.content.simple.expr != '') {
			hasMsg = true;
		} else if (system.content.hasOwnProperty('composite') && system.content.composite.hasOwnProperty('subSys')) {
			hasMsg = true;
		}
	}
	if (system.getDeriveFlag() == SENDER) {
		this.drawTriangle(x + w + deriveOffset, y + h / 2, deriveOffset, h, 'gray', ctx, _dss_editor._model.system.DIR_EAST);
		if (hasMsg) {
			ctx.fillStyle = 'blue';
			var l = 6;
			ctx.fillRect(x + w + 1, y + h / 2 - l / 2, l, l);
		}
	}
	if (system.getDeriveFlag() == RECEIVER) {
		this.drawTriangle(x + deriveOffset, y + h / 2, deriveOffset, h, 'white', ctx, _dss_editor._model.system.DIR_EAST);
		if (hasMsg) {
			ctx.fillStyle = 'blue';
			var l = 6;
			ctx.fillRect(x + 1, y + h / 2 - l / 2, l, l);
		}
	}

};

_dss_editor._canvas._system_layer.drawSimpleProDir = function(ctx, bounds, system) {
	// var dir = ' → ';
	// var reDir = ' ← ';
	ctx.strokeStyle = 'lightgray';
	ctx.beginPath();
	ctx.moveTo(bounds.x, bounds.y + bounds.h - labelHeight + 0.5);
	ctx.lineTo(bounds.x + bounds.w, bounds.y + bounds.h - labelHeight + 0.5);
	ctx.closePath();
	ctx.stroke();
	ctx.fillStyle = 'green';
	var direct = system.getFrom() + PRODIR + system.getTo();
	ctx.fillText(direct, bounds.x + 10, bounds.y + bounds.h - 10);
};

/* 绘制DSC图中显示名称的Label */
_dss_editor._canvas._system_layer.drawLabel = function(system, ctx, canvasType) {
	//var ctx = _dss_editor._toolkit.getContext(canvas.entity);
	var bounds = _dss_editor._toolkit.translateToAbsolute(system);
	var x = bounds.x + 0.5;
	var y = bounds.y + labelHeight + 0.5;
	var labelLength = minLabelLen;
	// 圆角所需
	var radius = 4;
	// 圆角的半径
	var startAngle = 0;
	// 弧线开始的角度
	var endAngle = 0;
	// 弧线结束的角度
	// 二次贝塞尔曲线控制点坐标
	var cpx = 0;
	var cpy = 0;
	var cpLen = 15;
	// 贝塞尔曲线的横向长度
	var cpHight = 14;
	// 贝塞尔曲线的纵向长度
	var cpXOffset = 6;
	// 贝塞尔曲线X坐标的偏移量
	// 图标的坐标
	var iconX = bounds.x + 3;
	var iconY = bounds.y + 2;
	// 文字的坐标
	var text = _dss_editor._model.system.getLabelText(system);
	var textX = bounds.x + 20;
	var textY = bounds.y + cpLen;
	var textSpace = 40;
	// 留给文字的空间
	// 参数暂时不做考虑
	// if(system.hasOwnProperty("tmplParam") && system.tmplParam.length >
	// 0){
	// text = text.concat("(");
	// for(var i = 0 ; i < system.tmplParam.length ; i++){
	// text = text.concat(system.tmplParam[i]);
	// if(i < system.tmplParam.length - 1){
	// text = text.concat(",");
	// }
	// }
	// text = text.concat(")");
	// }
	if (system.getType() == _dss_editor._model.system._type.NAMELABEL) {
		text = system.specSys.nameLabel.nameLabel;
	}

	var textLength = ctx.measureText(text).width;

	// 如果字符的长度大于label的最小长度，那么修改label的长度/
	if (textLength + textSpace > labelLength) {
		labelLength = textLength + textSpace;
	}
	if (labelLength > bounds.w) {
		labelLength = bounds.w;
		if (textLength + textSpace > labelLength) {
			text = _dss_editor._model.system.getTrimStr(labelLength - 30, text, ctx);
		}
	}

	// 开始画图-----------------------------
	if (system.isShowContent()) {
		// ctx.strokeStyle = getSystemColor(system);
		ctx.beginPath();
		// 先将坐标移动到指定位置
		ctx.moveTo(x, y);

		// 画竖线
		y -= labelHeight - radius;
		ctx.lineTo(x, y);

		// 画圆角
		startAngle = Math.PI;
		endAngle = -startAngle / 2;
		x += radius;
		ctx.arc(x, y, radius, startAngle, endAngle, false);
		// 画横线
		x += labelLength - 2 * cpLen;
		y -= radius;
		ctx.lineTo(x, y);
		// 画右边的弧线 上半部分 使用贝塞尔曲线
		cpx = x + cpXOffset;
		cpy = y;
		x += cpLen;
		y += cpHight;
		ctx.quadraticCurveTo(cpx, cpy, x, y);

		// 画右边的弧线 下半部分 使用贝塞尔曲线
		y += cpHight;
		x += cpLen;
		cpx = x - cpXOffset;
		cpy = y;
		ctx.quadraticCurveTo(cpx, cpy, x, y);

		ctx.closePath();
		ctx.fillStyle = 'white';
		ctx.fill();
		ctx.stroke();
	} else {
		textY += 5;
		textX += 8;
		iconX += 8;
		iconY += 5;
		ctx.save();
		if (system.hasShadow() == SHOW) {
			ctx.shadowBlur = 1;
			ctx.shadowColor = 'gray';
			ctx.shadowOffsetX = 3;
			ctx.shadowOffsetY = 3;
		}
		ctx.fillStyle = 'white';
		if (system.getDeriveFlag() == SENDER) {
			bounds.w -= deriveOffset;
		}
		this.fillRoundedRectangle(bounds, ctx);
		ctx.restore();
		this.strokeRoundedRectangle(bounds, ctx);
		this.drawDeriveFlag(system, ctx, bounds.x, bounds.y, bounds.w, bounds.h);
	}

	// 画System的图标
	if (canvasType != _dss_editor._canvas._type.VIEWUIO) {
		var icon = new Image();
		icon.src = _dss_editor._model.system.getSystemIcon(system);

		// 这个地方绘制，避免在重绘的时候出现图片闪烁的情况
		// setTimeout(ctx.drawImage(icon, iconX, iconY), 100);
		// 图片加载好后绘制，避免画不出来的问题
		// icon.onload = function() {
		ctx.drawImage(icon, iconX, iconY);
		// };
	} else {
		if (system.getDeriveFlag() == SENDER) {
			text = _dss_editor._toolkit.strReplaceAll(text, '_s', '');
		} else if (system.getDeriveFlag() == RECEIVER) {
			text = _dss_editor._toolkit.strReplaceAll(text, '_r', '');
		}
	}
	if (text.indexOf(namePrefix) != 0) {
		if (system.getType() == _dss_editor._model.system._type.NAMELABEL) {
			text = system.specSys.nameLabel.nameLabel;
			ctx.strokeStyle = 'black';
			ctx.strokeText(text, textX, textY);
		} else {
			ctx.fillStyle = 'black';
			ctx.fillText(text, textX, textY);
		}
	}
	//绘制staticCnt
	if (system.hasShadow()) {
		var l = ctx.measureText(system.getStaticCnt()).width + 5;
		ctx.fillText(system.getStaticCnt(), bounds.x + bounds.w - l, textY);
	}
};

/* 画System的方法 */
_dss_editor._canvas._system_layer.drawSystem = function(system, ctx, canvasType) {
	if (!system.isVisible()) {
		return;
	}
	if (system.getType() === COMMENT) {
		this.drawComment(system, ctx);
	} else {
		if (system.isShowContent()) {
			if (system.isShowLabel()) {
				this.drawLabel(system, ctx, canvasType);
			}
			this.drawContentBox(system, ctx, canvasType);
		} else {
			this.drawLabel(system, ctx, canvasType);
		}
	}

};

_dss_editor._canvas._system_layer.drawSystems = function(diagrams, canvas) {
	console.time('a');
	var ctx = _dss_editor._toolkit.getContext(canvas.entity);
	var canvasType = canvas.type;
	for (var i = 0; i < diagrams.length; i++) {
		var system = diagrams[i];
		this.drawDiagram(system, ctx, canvasType);
		// if (system.style == ARRAY) {
		// this.drawArray(system, ctx, canvasType);
		// } else {
		// this.drawSystem(system, ctx, canvasType);
		// }
	}
	for (var i = 0; i < canvas.selectionDiagrams.length; i++) {
		var system = canvas.selectionDiagrams[i];
		this.drawSelectionHandle(system, ctx);
		for (var j in system.handles) {
			var handle = system.handles[j];
			if ( handle instanceof HandleTool) {
				handle.draw();
			}
		}
	}
};

_dss_editor._canvas._system_layer.drawPoint = function(point, style, ctx) {
	// var system = getPoint();
	var bounds = _dss_editor._toolkit.translateToAbsolute(point);
	var x = bounds.x + 5;
	var y = bounds.y + 5;
	var w = 14;
	//bounds.w;
	var h = 14;
	//bounds.h;

	ctx.fillStyle = style;
	ctx.strokeRect(x + 0.5, y + 0.5, w, h);
	ctx.fillRect(x + 0.5, y + 0.5, w, h);

	// for ( var i in point.handles) {
	// var handle = point.handles[i];
	// handle.draw();
	// }
};

/* 画起点的方法 */
_dss_editor._canvas._system_layer.drawBeginPoint = function(point, ctx) {
	this.drawPoint(point, 'white', ctx);
};

/* 画终点的方法 */
_dss_editor._canvas._system_layer.drawEndPoint = function(point, ctx) {
	this.drawPoint(point, 'gray', ctx);
};

_dss_editor._canvas._system_layer.drawCondition = function(condition, ctx, color) {
	// var ctx = _dss_editor._toolkit.getContext(canvasEntity);
	var radius = 7;
	var loc = _dss_editor._model.link.getAnchorPoint(condition.parent, condition.showInfo.angle);
	var dir = _dss_editor._toolkit.calculatePointDir(loc, condition.parent);

	if (dir == _dss_editor._model.system.DIR_EAST) {
		loc.x -= radius;
		//loc.y -= radius;
	} else if (dir == _dss_editor._model.system.DIR_WEST) {
		loc.x += radius;
		//loc.y -= radius;
	} else if (dir == _dss_editor._model.system.DIR_NORTH) {
		//loc.x -= radius;
		loc.y += radius;
	} else if (dir == _dss_editor._model.system.DIR_SOUTH) {
		//loc.x -= radius;
		loc.y -= radius;
	}

	ctx.fillStyle = color;
	ctx.moveTo(loc.x, loc.y);
	ctx.beginPath();
	ctx.arc(loc.x, loc.y, radius, 2 * Math.PI, 0, true);
	ctx.closePath();
	ctx.stroke();
	ctx.fill();
};

/* 画前置条件的方法 */
_dss_editor._canvas._system_layer.drawPreCondition = function(condition, canvasEntity) {
	this.drawCondition(condition, canvasEntity, 'white');
};

/* 画后置条件的方法 */
_dss_editor._canvas._system_layer.drawPostCondition = function(condition, ctx) {
	this.drawCondition(condition, ctx, 'gray');
};

_dss_editor._canvas._system_layer.drawExitPoint = function(point, ctx) {
	var loc = _dss_editor._model.link.getAnchorPoint(point.parent, point.showInfo.angle);
	var logic = null;
	var dir = _dss_editor._toolkit.calculatePointDir(loc, point.parent);
	// var ctx = _dss_editor._toolkit.getContext(canvasEntity);
	if (point.name == 'OR') {
		logic = EXIT_OR;
	} else if (point.name == 'AND') {
		logic = EXIT_AND;
	} else if (point.name == 'XOR') {
		logic = EXIT_XOR;
	}

	if (logic != null) {

		var textW = ctx.measureText(logic).width;
		switch (dir) {
			case _dss_editor._model.system.DIR_EAST:
				loc.x -= textW + 5;
				loc.y += 5;
				break;
			case _dss_editor._model.system.DIR_NORTH:
				loc.x -= textW / 2;
				loc.y += 14;
				break;
			case _dss_editor._model.system.DIR_SOUTH:
				loc.y -= 5;
				loc.x -= textW / 2;
				break;
			default:
				loc.x += 5;
				loc.y += 5;
				break;
		}
		ctx.fillText(logic, loc.x, loc.y);
	} else {
		var height = 16;
		var bottomLen = 14;
		this.drawTriangle(loc.x, loc.y, height, bottomLen, 'gray', ctx, dir);
	}
};
_dss_editor._canvas._system_layer.drawSelectionHandle = function(system, ctx) {
	var bounds = _dss_editor._toolkit.translateToAbsolute(system);
	ctx.strokeStyle = 'green';
	ctx.lineWidth = 2;
	ctx.strokeRect(bounds.x + 0.5, bounds.y + 0.5, bounds.w, bounds.h);
};
_dss_editor._canvas._system_layer.drawComment = function(comment, ctx) {
	var bounds = _dss_editor._toolkit.translateToAbsolute(comment);
	this.drawDashRectangle(bounds, ctx);
	ctx.fillStyle = 'green';
	//textX -= 10;	
	this.drawHtmlText(comment.getValue(), bounds.x + 10, bounds.y + 15, bounds.w, bounds.h, ctx);

};

_dss_editor._canvas._system_layer.drawDashRectangle = function(bounds, ctx) {
	var x = bounds.x + 0.5;
	var y = bounds.y + 0.5;
	var w = bounds.w;
	var h = bounds.h;
	var dashlen = 3;
	var cur = 0;
	//当前画笔所在位置

	ctx.beginPath();
	ctx.moveTo(x, y);
	//draw top
	while (cur < w) {
		cur += dashlen;
		if(cur > w){
			cur = w;
		}
		ctx.lineTo(x + cur, y);
		cur += dashlen;
		ctx.moveTo(x + cur, y);
	}
	//draw right

	cur = 0;
	ctx.moveTo(x + w, y);
	while (cur < h) {
		cur += dashlen;
		if(cur > h){
			cur = h;
		}
		ctx.lineTo(x + w, y + cur);
		cur += dashlen;
		ctx.moveTo(x + w, y + cur);
	}
	//draw bottom
	cur = 0;
	ctx.moveTo(x + w, y + h);
	while (cur < w) {
		cur += dashlen;
		if(cur > w){
			cur = w;
		}
		ctx.lineTo(x + w - cur, y + h);
		cur += dashlen;
		ctx.moveTo(x + w - cur, y + h);
	}
	//draw left
	cur = 0;
	ctx.moveTo(x, y + h);
	while (cur < h) {
		cur += dashlen;
		if(cur > h){
			cur = h;
		}
		ctx.lineTo(x, y + h - cur);
		cur += dashlen;
		ctx.moveTo(x, y + h - cur);
	}

	ctx.stroke();

};

_dss_editor._canvas._system_layer.fillRoundedRectangle = function(bounds, ctx) {
	this.drawRoundedRectangle(bounds, ctx);
	ctx.fillStyle = 'white';
	ctx.fill();
};
_dss_editor._canvas._system_layer.strokeRoundedRectangle = function(bounds, ctx) {
	this.drawRoundedRectangle(bounds, ctx);
	ctx.stroke();
};
_dss_editor._canvas._system_layer.drawRoundedRectangle = function(bounds, ctx) {
	var x = bounds.x + 1;
	var y = bounds.y + 0.5;
	var w = bounds.w;
	var h = bounds.h;

	// 圆角所需
	var radius = 3;
	// 圆角的半径
	var startAngle = 0;
	// 弧线开始的角度
	var endAngle = 0;
	// 弧线结束的角度
	// 开始画图-----------------------------
	ctx.beginPath();
	// 先将坐标移动到指定位置
	ctx.moveTo(x, y);

	// 画圆角
	startAngle = Math.PI;
	endAngle = -Math.PI / 2;
	y += radius;
	x += radius / 2;
	ctx.arc(x, y, radius, startAngle, endAngle, false);

	// 画横线
	x += w - 2 * radius;
	y -= radius;
	ctx.lineTo(x, y);
	// 画圆角
	startAngle = -Math.PI / 2;
	endAngle = 0;
	// x += radius;
	y += radius;
	ctx.arc(x, y, radius, startAngle, endAngle, false);
	// 画竖线
	y += h - 2 * radius;
	x += radius;
	ctx.lineTo(x, y);
	// 画圆角
	startAngle = 0;
	endAngle = Math.PI / 2;
	x -= radius;
	ctx.arc(x, y, radius, startAngle, endAngle, false);
	// 画横线
	x -= w - 2 * radius;
	y += radius;
	ctx.lineTo(x, y);
	// 画圆角
	startAngle = Math.PI / 2;
	endAngle = Math.PI;
	// x -= radius;
	y -= radius;
	ctx.arc(x, y, radius, startAngle, endAngle, false);
	// 画竖线
	y -= h - 2 * radius;
	x -= radius;
	ctx.lineTo(x, y);
	// ctx.fillStyle = 'white';
	// if (style === 'fill') {
	// ctx.fill();
	// } else {
	// ctx.stroke();
	// }
};
_dss_editor._canvas._system_layer.drawTriangle = function(x, y, height, bottomLen, color, ctx, dir) {
	// var ctx = _dss_editor._toolkit.getContext(canvasEntity);
	ctx.beginPath();
	ctx.fillStyle = color;
	var x1 = x, y1 = y;

	switch (dir) {
		case _dss_editor._model.system.DIR_WEST:
			ctx.lineTo(x1 + height, y1 - bottomLen / 2);
			ctx.lineTo(x1 + height, y1 + bottomLen / 2);
			ctx.lineTo(x, y);
			break;
		case _dss_editor._model.system.DIR_NORTH:
			ctx.lineTo(x1 - bottomLen / 2, y1 + height);
			ctx.lineTo(x1 + bottomLen / 2, y1 + height);
			ctx.lineTo(x, y);
			break;
		case _dss_editor._model.system.DIR_SOUTH:
			ctx.lineTo(x1 - bottomLen / 2, y1 - height);
			ctx.lineTo(x1 + bottomLen / 2, y1 - height);
			ctx.lineTo(x, y);
			break;
		default:
			ctx.lineTo(x1 - height, y1 - bottomLen / 2);
			ctx.lineTo(x1 - height, y1 + bottomLen / 2);
			ctx.lineTo(x, y);
			break;
	}

	ctx.closePath();
	ctx.fill();
	ctx.stroke();
};
_dss_editor._canvas._system_layer.drawFeedback = function(bounds, canvas) {
	// var bounds = translateToAbsolute(diagram);
	var ctx = _dss_editor._toolkit.getContext(canvas.entity);
	ctx.save();
	ctx.globalAlpha = 0.5;
	ctx.fillStyle = 'lightgray';
	ctx.fillRect(bounds.x, bounds.y, bounds.w, bounds.h);
	ctx.strokeRect(bounds.x, bounds.y, bounds.w, bounds.h);
	ctx.restore();
};
_dss_editor._canvas._system_layer.drawHtmlText = function(text, x, y, width, height, ctx) {
	ctx.fillStyle = 'green';
	var bold = false, italic = false, inTag = false, isOver = false, hasDiv = false;
	var start = x;
	var drawedText = '';
	var textHeight = 0;
	var rowHeight = 16;
	var tagStart = '<', tagEnd = '>', tagOver = '/';
	var specStart = '&', specEnd = ';';
	//特殊字符
	var tag = '';
	//return true 表示可以换行 return false 表示不能换行
	var beginNewLine = function() {
		textHeight += rowHeight;
		//如果换行之后高度 高过了 图元的高度，则加省略号表示未显示完整
		if (textHeight + 20 >= height) {
			ctx.fillText('...', x, y);
			return false;
		} else {
			x = start;
			y += rowHeight;
			drawedText = '';
			return true;
		}
	};
	ctx.save();
	for (var i = 0; i < text.length; i++) {
		// console.log(text[i]);
		var font = '10pt Calibri';
		if (text[i] == tagStart || text[i] == specStart) {
			inTag = true;
			continue;
		} else if (text[i] == tagEnd || text[i] == specEnd) {
			if (tag == 'b') {
				if (isOver) {
					bold = false;
				} else {
					bold = true;
				}
			} else if (tag == 'i') {
				if (isOver) {
					italic = false;
				} else {
					italic = true;
				}
			} else if (tag == 'br') {
				if (!beginNewLine()) {
					break;
				}
			} else if (tag == 'div') {
				if (isOver) {
					hasDiv = false;
				} else {
					if (!hasDiv) {
						if (!beginNewLine()) {
							break;
						}
					}
					hasDiv = true;
				}
			} else if (tag == 'gt') {
				//ctx.font = font;
				ctx.fillText('>', x, y);
				x += ctx.measureText('>').width;
				drawedText += '>';
			} else if (tag == 'lt') {
				//ctx.font = font;
				ctx.fillText('<', x, y);
				x += ctx.measureText('<').width;
				drawedText += '<';
			} else if (tag == '#13') {
				if (!beginNewLine()) {
					break;
				}
			}
			inTag = false;
			isOver = false;
			tag = '';
			continue;
		} else if (text[i] == tagOver) {
			isOver = true;
			continue;
		}

		if (inTag) {
			tag += text[i];
			continue;
		}

		if (bold) {
			font = 'bold ' + font;
		}
		if (italic) {
			font = 'italic ' + font;
		}
		//如果一行字的宽度超过了范围 则换行
		if (ctx.measureText(drawedText).width >= width - 30) {
			if (!beginNewLine()) {
				break;
			}
		}
		ctx.font = font;
		ctx.fillText(text[i], x, y);
		x += ctx.measureText(text[i]).width;
		drawedText += text[i];
	}
    ctx.restore();
};

_dss_editor._canvas._link_layer.create = function(canvas) {
	var layer = {};
	layer.canvas = canvas;
	var that = this;
	layer.layout = function() {
        
	};
	layer.draw = function() {
		that.drawLinks(this.canvas);
	};
	return layer;
};
_dss_editor._canvas._link_layer.drawLine = function(style, lineWidth, text, x1, y1, x2, y2, ctx) {
	// var ctx = _dss_editor._toolkit.getContext(canvasEntity);
	var dashLen = 3;
	ctx.lineWidth = lineWidth;

	x1 += 0.5;
	y1 += 0.5;
	x2 += 0.5;
	y2 += 0.5;

	// 由于连线可能会倾斜，所以XY的偏移量需要进行计算
	var lineLen = Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));
	var sina = (y2 - y1) / lineLen;
	var cosa = (x2 - x1) / lineLen;
	var tempX = dashLen * cosa;
	var tempY = dashLen * sina;
	var textX = (x1 + x2) / 2;
	var textY = (y1 + y2) / 2;
	// 以下判断作为临时的处理
	var angle = Math.acos(cosa);
	if (y1 > y2) {
		angle = -angle;
	}

	ctx.beginPath();
	if (style == LINE_STYLE_SOLID) {
		ctx.moveTo(x1, y1);
		ctx.lineTo(x2, y2);
	} else {
		while (Math.abs(x2 - x1) > dashLen || Math.abs(y2 - y1) > dashLen) {
			ctx.moveTo(x1 + tempX, y1 + tempY);
			x1 += 2 * tempX;
			y1 += 2 * tempY;
			ctx.lineTo(x1, y1);
		}
	}

	// if ( text instanceof Array) {
	// console.log("array");
	// } else {
	// var textLen = ctx.measureText(text).width;
	// textX -= textLen / 2;
	// ctx.fillText(text, textX, textY);
	// }
	ctx.stroke();

	return angle;
};

_dss_editor._canvas._link_layer.drawLink = function(link, ctx, srcPoint, tarPoint, style, lineWidth) {
	var from = srcPoint;
	var to = tarPoint;
	var angle = 0;
	// var ctx = _dss_editor._toolkit.getContext(canvasEntity);

	if (link.hasOwnProperty('linkType')) {
		if (link.hasOwnProperty('bendPoints')) {
			for (var i in link.bendPoints) {
				var bp = link.bendPoints[i](from, to);
				to = bp;
				this.drawLine(style, lineWidth, link.content, from.x, from.y, to.x, to.y, ctx);
				from = bp;
			}
		}
		if (link.hasOwnProperty('getEditArea') && link.hasOwnProperty('content') && link.content != null) {
			var textP = link.getEditArea();
			textP.y += 5;
			textP.x += ctx.measureText(link.content).width/2;
			ctx.fillText(link.content, textP.x, textP.y);
		}
		angle = this.drawLine(style, lineWidth, link.content, from.x, from.y, tarPoint.x, tarPoint.y, ctx);

	}
	return angle;
};

_dss_editor._canvas._link_layer.drawArraw = function(x, y, angle, location, ctx) {
	// var ctx = _dss_editor._toolkit.getContext(canvasEntity);
	var arrawLen = 8;
	var arrayAngle = Math.PI / 6;
	// var newX = newY = 0;

	if (location == ARRAW_SRC) {
		arrayAngle = Math.PI - arrayAngle;
	}
	ctx.beginPath();
	ctx.translate(x, y);
	ctx.rotate(angle);

	ctx.moveTo(-arrawLen * Math.cos(arrayAngle), arrawLen * Math.sin(arrayAngle));
	ctx.lineTo(0, 0);
	ctx.lineTo(-arrawLen * Math.cos(arrayAngle), -arrawLen * Math.sin(arrayAngle));

	ctx.rotate(2 * Math.PI - angle);
	ctx.translate(-x, -y);
	ctx.stroke();
};

// 继承线的箭头
_dss_editor._canvas._link_layer.drawRectArraw = function(x, y, angle, location, ctx) {
	// var ctx = _dss_editor._toolkit.getContext(canvasEntity);
	var arrawLen = 6;
	var arrawX = -arrawLen;
	var arrawY = -arrawLen / 2;
	if (location == ARRAW_SRC) {
		arrawX = 0;
	}

	ctx.beginPath();
	ctx.translate(x, y);
	ctx.rotate(angle);
	ctx.moveTo(0, 0);
	ctx.fillRect(arrawX, arrawY, arrawLen, arrawLen);
	ctx.rotate(2 * Math.PI - angle);
	ctx.translate(-x, -y);
};

// 关系连线的箭头
_dss_editor._canvas._link_layer.drawArcArraw = function(x, y, angle, location, ctx) {
	// var ctx = _dss_editor._toolkit.getContext(canvasEntity);
	var arrawRadius = 4;
	if (location == ARRAW_SRC) {
		arrawX = 0;
	}
    ctx.save();
	ctx.beginPath();
	ctx.translate(x, y);
	ctx.moveTo(0, 0);
	ctx.arc(0, 0, arrawRadius, 2 * Math.PI, 0, true);
	ctx.fill();
	ctx.restore();
};
// 画连线的方法
_dss_editor._canvas._link_layer.drawTransition = function(link, ctx, srcPoint, tarPoint) {
	var lineStyle = LINE_STYLE_SOLID;
	var lineWidth = 1;
	var lineAngle = this.drawLink(link, ctx, srcPoint, tarPoint, lineStyle, lineWidth);
	this.drawArraw(tarPoint.x, tarPoint.y, lineAngle, ARRAW_TAR, ctx);
};

_dss_editor._canvas._link_layer.drawInteraction = function(link, ctx, srcPoint, tarPoint) {
	var lineStyle = LINE_STYLE_DASH;
	var lineWidth = 2;
	var lineAngle = this.drawLink(link, ctx, srcPoint, tarPoint, lineStyle, lineWidth);
	this.drawArraw(tarPoint.x, tarPoint.y, lineAngle, ARRAW_TAR, ctx);
	if (link.biConnection == TRUE) {
		this.drawArraw(srcPoint.x, srcPoint.y, lineAngle, ARRAW_SRC, ctx);
	};
	//	if(conn.getEditArea){
	//		var ctx = _dss_editor._toolkit.getContext(canvasEntity);
	//		ctx.strokeRect(conn.getEditArea().x,conn.getEditArea().y,conn.getEditArea().w,conn.getEditArea().h);
	//	}
};

_dss_editor._canvas._link_layer.drawCreate = function(link, ctx, srcPoint, tarPoint) {
	var lineStyle = LINE_STYLE_DASH;
	var lineWidth = 5;
	var lineAngle = this.drawLink(link, ctx, srcPoint, tarPoint, lineStyle, lineWidth);
	this.drawArraw(tarPoint.x, tarPoint.y, lineAngle, ARRAW_TAR, ctx);
};

_dss_editor._canvas._link_layer.drawRelation = function(link, ctx, srcPoint, tarPoint) {
	var lineStyle = LINE_STYLE_SOLID;
	var lineWidth = 1;
	var lineAngle = this.drawLink(link, ctx, srcPoint, tarPoint, lineStyle, lineWidth);
	//this.drawArcArraw(tarPoint.x, tarPoint.y, lineAngle, ARRAW_TAR, ctx);
	this.drawArcArraw(srcPoint.x, srcPoint.y, lineAngle, ARRAW_SRC, ctx);
	if (link.biConnection == TRUE) {
		this.drawArcArraw(srcPoint.x, srcPoint.y, lineAngle, ARRAW_SRC, ctx);
	}
};

_dss_editor._canvas._link_layer.drawInheritance = function(link, ctx, srcPoint, tarPoint) {
	var lineStyle = LINE_STYLE_SOLID;
	var lineWidth = 1;
	var lineAngle = this.drawLink(link, ctx, srcPoint, tarPoint, lineStyle, lineWidth);
	this.drawRectArraw(tarPoint.x, tarPoint.y, lineAngle, ARRAW_TAR, ctx);
};

_dss_editor._canvas._link_layer.drawCommonLink = function(link, ctx, srcPoint, tarPoint) {
	var lineStyle = LINE_STYLE_DASH;
	var lineWidth = 2;
	this.drawLink(link, ctx, srcPoint, tarPoint, lineStyle, lineWidth);
};

_dss_editor._canvas._link_layer.drawLinks = function(canvas) {
	var links = canvas.links;
	var ctx = _dss_editor._toolkit.getContext(canvas.entity);
	for (var i in links) {
		var link = links[i];
		if (getValue(link.showInfo.visible) == NO || link.getFromSystem() == null || link.getToSystem() == null) {
			continue;
		}
		var srcPoint = _dss_editor._model.link.getAnchorPoint(link.getFromSystem(), link.showInfo.fromAngle);
		var tarPoint = _dss_editor._model.link.getAnchorPoint(link.getToSystem(), link.showInfo.toAngle);
		// if(link.getFromSystem().)
		if (link.linkType) {
			this.drawLinkByType(link, ctx, srcPoint, tarPoint);
		}
	}
	for (var j = 0; j < canvas.selectionLinks.length; j++) {
		var l = canvas.selectionLinks[j];
		for (var i in l.handles) {
			var handle = l.handles[i];
			if (handle.hasOwnProperty('draw')) {
				handle.draw();
			}
		}
	}
};

// 根据link的类型判断绘制什么类型的link
_dss_editor._canvas._link_layer.drawLinkByType = function(link, ctx, srcPoint, tarPoint) {
	if (link.linkType == TYPE_TRANSITION) {
		this.drawTransition(link, ctx, srcPoint, tarPoint);
	} else if (link.linkType == TYPE_INTERACTION) {
		this.drawInteraction(link, ctx, srcPoint, tarPoint);
	} else if (link.linkType == TYPE_CREATE) {
		this.drawCreate(link, ctx, srcPoint, tarPoint);
	} else if (link.linkType == TYPE_RELATION) {
		this.drawRelation(link, ctx, srcPoint, tarPoint);
	} else if (link.linkType == TYPE_INHERITANCE) {
		this.drawInheritance(link, ctx, srcPoint, tarPoint);
	} else if (link.linkType == TYPE_CREATE) {
		this.drawCreate(link, ctx, srcPoint, tarPoint);
	} else {
		this.drawCommonLink(link, ctx, srcPoint, tarPoint);
	}
};
_dss_editor._canvas._link_layer.drawLinkFeedBack = function(canvas, sourcePoint, targetPoint, link, eventObj) {
	canvas.update();
	var ctx = _dss_editor._toolkit.getContext(canvas.entity);
	this.drawLinkByType(link, ctx, sourcePoint, targetPoint);
	if (_dss_editor._canvas._operation.viewOp.moveAroundDiagram(canvas, eventObj.location) || canvas.onDiagram.style == POINT) {
		canvas.entity.style.cursor = 'crosshair';
	} else {
		canvas.entity.style.cursor = 'no-drop';
	}
};

